package com.zmn.oms.business.impl.apply;

import com.google.common.collect.Lists;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.business.interfaces.apply.CancelApplyBService;
import com.zmn.oms.business.interfaces.mq.MqProviderService;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.model.bo.work.apply.cancel.CancelApplyReasonBO;
import com.zmn.oms.model.bo.work.apply.cancel.CancelApplyResultBO;
import com.zmn.oms.model.entity.masterworking.MasterWorking;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.services.interfaces.datasync.ElasticSearchDataSyncService;
import com.zmn.oms.services.interfaces.masterworking.MasterWorkingService;
import com.zmn.oms.services.interfaces.order.OrderChangeService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.track.common.constant.apply.cancel.CancelApplyConsts;
import com.zmn.track.common.constant.apply.cancel.CancelApplyLogConsts;
import com.zmn.track.common.dto.apply.cancel.QueueApplyCancelDataDTO;
import com.zmn.track.dubbo.dio.apply.cancel.OrderCancelApplyQuery;
import com.zmn.track.dubbo.dro.apply.cancel.OrderCancelApplyDRO;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * @Author: wyc
 * @Description: 取消申请业务处理类
 * @Date: 2022/5/25 22:09
 * @Version: 1.0
 */
@Slf4j
@Service
public class CancelApplyBServiceImpl implements CancelApplyBService {

    // 限定节点
    private final List<Integer> RESTRICT_NODE_LIST = Lists.newArrayList(
            CancelApplyLogConsts.CANCEL_LOG_TYPE_REVIEW_INIT,
            CancelApplyLogConsts.CANCEL_LOG_TYPE_REVIEW_FINISH
    );

    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyListRemoteService orderCancelApplyListRemoteService;
    //@Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    //private TouchModifyRemoteService touchModifyRemoteService;

    @Autowired
    private MqProviderService mqProviderService;
    @Autowired
    private MasterWorkingService masterWorkingService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderChangeService orderChangeService;
    @Autowired
    private ElasticSearchDataSyncService elasticSearchDataSyncService;


    @Override
    public void changeWaitCancelStatus(QueueApplyCancelDataDTO messageDto) {

        if (!RESTRICT_NODE_LIST.contains(messageDto.getNodeType())) {
            return;
        }
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(messageDto.getOrderId(), messageDto.getWorkId());

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            log.info("{} 工单不在进行中则不处理", messageDto.getWorkId());
            return;
        }

        OrderCancelApplyQuery applyQuery = OrderCancelApplyQuery
                .builder()
                .applyId(messageDto.getApplyId())
                .orderId(messageDto.getOrderId())
                .workId(messageDto.getWorkId())
                .build();
        log.info("{}根据条件查询取消申请#listCancelApplyByQuery query={}", messageDto.getWorkId(), applyQuery);
        ResponseDTO<List<OrderCancelApplyDRO>> listResponseDTO = orderCancelApplyListRemoteService.listCancelApplyByQuery(applyQuery);
        log.info("{}根据条件查询取消申请#listCancelApplyByQuery listResponseDTO={}", messageDto.getWorkId(), listResponseDTO);
        if (!listResponseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(listResponseDTO.getData())) {
            log.error("查询取消申请为null");
            return;
        }
        // 通过主键查询只有一个
        OrderCancelApplyDRO orderCancelApplyDRO = listResponseDTO.getData().get(0);
        if (!Objects.equals(orderCancelApplyDRO.getNeedReview(), GlobalConsts.YES)) {
            // 无需审核不需要处理
            return;
        }

        List<Integer> reviewStatusList = Lists.newArrayList(
                CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK,
                CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK_FAIL,
                CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK_EFFICACY
        );

        if (!reviewStatusList.contains(orderCancelApplyDRO.getReviewStatus())) {
            return;
        }

        // 修改工程师列表取消状态
        List<Integer> waitCancelReviewStatusList = Lists.newArrayList(CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK, CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK_PROCESSING);
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(orderCancelApplyDRO.getWorkId());
        masterWorking.setWaitCancel(
                waitCancelReviewStatusList.contains(orderCancelApplyDRO.getReviewStatus()) ? GlobalConsts.YES : GlobalConsts.NO
        );
        masterWorkingService.updateMasterWorking(masterWorking);
        //touchModifyRemoteService.saveWorkVersion(orderWork.getMasterId(), null);
        mqProviderService.sendEngineerWorkVersion(orderWork.getMasterId(), null);

        // 修改用户订单 取消状态
        if (Objects.equals(orderCancelApplyDRO.getApplySource(), CancelApplyConsts.CANCEL_APPLY_SOURCE_USER_CLIENT)) {
            // 同步通知mos修改cancelApplyStatus字段
            orderChangeService.changeSyncToMos(messageDto.getOrderId());
            // mq同步es更改waitCancel字段
            elasticSearchDataSyncService.syncWorkIndex(messageDto.getOrderId());
        }
    }

    @Override
    public OperatePermissionVO getOperatePermission(Long orderId, Long workId) {
        CancelApplyResultBO waitCancelInfo = this.getWaitCancelInfo(orderId, workId);
        if (Objects.equals(waitCancelInfo.getUserWaitCancelStatus(), GlobalConsts.YES)) {
            return OperatePermissionVO.fail("有待审核的取消申请，不可操作");
        }
        return OperatePermissionVO.success();
    }

    @Override
    public CancelApplyResultBO getWaitCancelInfo(Long orderId, Long workId) {
        CancelApplyResultBO resultBO = new CancelApplyResultBO();
        resultBO.setMasterWaitCancelStatus(GlobalConsts.NO);
        resultBO.setUserWaitCancelStatus(GlobalConsts.NO);


        OrderCancelApplyQuery orderCancelApplyQuery = new OrderCancelApplyQuery();
        orderCancelApplyQuery.setOrderId(orderId);
        orderCancelApplyQuery.setWorkId(workId);
        orderCancelApplyQuery.setReviewStatusList(Lists.newArrayList(CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK, CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK_PROCESSING));
        orderCancelApplyQuery.setSearchReason(GlobalConsts.YES);
        log.info("{}根据条件查询取消申请#listCancelApplyByQuery query={}", workId, orderCancelApplyQuery);
        ResponseDTO<List<OrderCancelApplyDRO>> listResponseDTO = orderCancelApplyListRemoteService.listCancelApplyByQuery(orderCancelApplyQuery);
        log.info("{}根据条件查询取消申请#listCancelApplyByQuery listResponseDTO={}", workId, listResponseDTO);
        if (!listResponseDTO.isSuccess()) {
            return resultBO;
        }
        if (CollectionUtil.isNullOrEmpty(listResponseDTO.getData())) {
            return resultBO;
        }

        List<OrderCancelApplyDRO> orderCancelApplyDROList = listResponseDTO.getData();
        orderCancelApplyDROList.sort(Comparator.comparing(OrderCancelApplyDRO::getCreateTime));
        resultBO.setMasterWaitCancelStatus(GlobalConsts.YES);
        resultBO.setCanelApplyTime(orderCancelApplyDROList.get(0).getCreateTime());
        resultBO.setCancelReasonList(BeanMapper.mapList(orderCancelApplyDROList.get(0).getCancelReasonList(), CancelApplyReasonBO.class));

        boolean isUserApply = orderCancelApplyDROList.stream()
                .anyMatch(e -> Objects.equals(e.getApplySource(), CancelApplyConsts.CANCEL_APPLY_SOURCE_USER_CLIENT));
        if (isUserApply) {
            resultBO.setUserWaitCancelStatus(GlobalConsts.YES);
        }

        return resultBO;
    }
}
